#include "SubtitleParser.h"

SubtitleParser::SubtitleParser(int idTrack, QObject *parent) : QThread(parent){
    this->idTrack = idTrack;
    nullTime = QTime(0, 0, 0);
}

SubtitleParser::~SubtitleParser(){
}

Mlt::Playlist *SubtitleParser::getSubtitlePlaylist(){
    return this->subtitlePlaylist;
}

void SubtitleParser::run(){
    QFile file(this->fileName);
    Mlt::Playlist *playlist; //TODO delete this->subtitlePlaylist
    if(file.open(QIODevice::ReadOnly | QIODevice::Text)){
        QTextStream inTextStream(&file);
        QList<SubtitleInfo> *subtitleInfos = this->_getAllSubtitleInfoAndCreateSvgFiles(inTextStream);
        playlist = this->_createPlaylist(*subtitleInfos);
        delete subtitleInfos;
    }else{
        std::cout << "Unable to open the file" << std::endl;
    }
    file.close();

    std::cout << "emit SubtitleParser::subtitleGenerated()" << std::endl;
    this->_addPlaylistInTractor(playlist, this->idTrack);
    emit subtitleGenerated();
}

void SubtitleParser::addSubtitleInTractor(Mlt::Tractor *tractor, int nFrames, QString fileName, int idTrack, QSize videoSize, QFont font, QColor color, double yPerc, double fps){
    this->_setFileName(fileName);
    this->_setVideoSize(videoSize);
    this->_setFont(font);
    this->_setColor(color);
    this->_setYPerc(yPerc);
    this->_setFps(fps);
    this->_setIdTrack(idTrack);
    this->_setTractor(tractor);
    this->_setNFrames(nFrames);
    if(!this->isRunning()){
        this->start();
        this->setPriority(QThread::HighPriority);
    }
    this->wait();
}

void SubtitleParser::_setFileName(QString fileName){
    this->fileName = fileName;
}

void SubtitleParser::_setVideoSize(QSize videoSize){
    this->videoSize = videoSize;
}

void SubtitleParser::_setFont(QFont font){
    this->font = font;
}

void SubtitleParser::_setColor(QColor color){
    this->color = color;
}

void SubtitleParser::_setYPerc(int yPerc){
    this->yPerc = yPerc;
}

void SubtitleParser::_setFps(double fps){
    this->fps = fps;
}

void SubtitleParser::_setIdTrack(int idTrack){
    this->idTrack = idTrack;
}

void SubtitleParser::_setTractor(Mlt::Tractor *tractor){
    this->tractor = tractor;
}

void SubtitleParser::_setNFrames(int nFrames){
    this->nFrames = nFrames;
}

QList<SubtitleInfo> *SubtitleParser::_getAllSubtitleInfoAndCreateSvgFiles(QTextStream &inTextStream){
    QList<SubtitleInfo> *subtitleInfos = new QList<SubtitleInfo>();
    while(!inTextStream.atEnd()){
        SubtitleInfo subtitleInfo = this->_getNextSubtitleInfo(inTextStream);
        this->_genereSvgFile(subtitleInfo);
        subtitleInfos->append(subtitleInfo);
    }
    return subtitleInfos;
}

SubtitleInfo SubtitleParser::_getNextSubtitleInfo(QTextStream &textStream){
    QString line = textStream.readLine();
    while(line == "\n"){
        line = textStream.readLine();
    }
    SubtitleInfo subInfo;
    subInfo.id = line.toInt(); //TODO may be remove the endl
    line = textStream.readLine();
    QStringList times = line.split(" --> ");
    QTime startTime = QTime::fromString(times.at(0));
    QTime endTime = QTime::fromString(times.at(1));
    subInfo.firstFrame = nullTime.secsTo(startTime)*fps;
    subInfo.lastFrame = nullTime.secsTo(endTime)*fps;
    line = textStream.readLine();
    while(line != ""){
        subInfo.texts.append(line);
        line = textStream.readLine();
    }
    return subInfo;
}

void SubtitleParser::_genereSvgFile(SubtitleInfo subtitleInfo){
    QSvgGenerator generator;
    QString svgFileName = this->_getSvgFileName(this->fileName, subtitleInfo.id);
    generator.setFileName(svgFileName);
    generator.setSize(this->videoSize);
    generator.setViewBox(QRect(0, 0, this->videoSize.width(), this->videoSize.height()));
    //generator.setTitle("Multimedia Learner subtitle");
    //generator.setDescription("useless I think");
    QPainter painter;
    painter.begin(&generator);
    painter.setFont(font);
    QPen pen(color);
    painter.setPen(pen);
    //int max_y = this->videoSize.height();
    //int fontSize = font.pointSize();
    int y = this->yPerc * this->videoSize.height() / 100;
    QString finalText(subtitleInfo.texts.at(0));
    for(int i=1; i<subtitleInfo.texts.length(); i++){
        finalText = finalText + "\n" + subtitleInfo.texts.at(i);
    }
    painter.drawText(QRectF(0, y, this->videoSize.width(), this->videoSize.height()), Qt::AlignHCenter, finalText);
    painter.end();
}

void SubtitleParser::_genereVoidSvg(QString svgFileName){
    QSvgGenerator generator;
    generator.setFileName(svgFileName);
    generator.setSize(this->videoSize);
    generator.setViewBox(QRect(0, 0, this->videoSize.width(), this->videoSize.height()));
    //generator.setTitle("Multimedia Learner subtitle");
    //generator.setDescription("useless I think");
    QPainter painter;
    painter.begin(&generator);
    painter.end();
}

QString SubtitleParser::_getSvgFileName(QString subtitleFileName, int id){
    QString svgFileName = subtitleFileName.left(subtitleFileName.length()-4) + QString("_") + QString("%1").arg(id) + ".svg";
    svgFileName = svgFileName.split("/").last(); //TODO check that this works under windows
    svgFileName = QDir::tempPath() + "/" + svgFileName;
    return svgFileName;
}

Mlt::Playlist *SubtitleParser::_createPlaylist(QList<SubtitleInfo> subtitleInfos){
    QString voidSvgFileName = QDir::tempPath() + "/void.svg";
    this->_genereVoidSvg(voidSvgFileName);
    Mlt::Profile profile("square_ntsc_wide");
    Mlt::Producer voidProducer(profile, voidSvgFileName.toUtf8().data());
    Mlt::Playlist *subtitlePlaylist = new Mlt::Playlist();


    Mlt::Playlist tempSubtitlePlaylist; //Because we cannot put too much clip in a playlist
    ///int nClipInTempSubtitlePlaylist = 30;
    int lastEndFrame = 0;
    ///int correction = 0;
    for(int i=0; i<subtitleInfos.count(); i++){
        SubtitleInfo subInfo = subtitleInfos.at(i);
        if(lastEndFrame+1 <= subInfo.firstFrame-1){
            ///tempSubtitlePlaylist.append(voidProducer, lastEndFrame+1-correction, subInfo.firstFrame-1-correction);
            subtitlePlaylist->append(voidProducer, lastEndFrame+1, subInfo.firstFrame-1);
        }else if(lastEndFrame == subInfo.firstFrame){
            subInfo.firstFrame++;
        }else if(lastEndFrame > subInfo.firstFrame){
            std::cout << "DEBUG :else if(lastEndFrame > subInfo.firstFrame)" << std::endl;
            subInfo.firstFrame = lastEndFrame + 1;
        }
        lastEndFrame = subInfo.lastFrame;

        QString svgFileName = this->_getSvgFileName(this->fileName, subInfo.id);
        Mlt::Producer producer(profile, svgFileName.toUtf8().data());

        //Mlt::Properties prop(producer.get_properties());
        //prop.set("in", 0); //TODO may be I don't need to define thos properties
        //prop.set("out", subInfo.lastFrame - subInfo.firstFrame);
        //prop.set("novdpau", 1); //I have no idea what this means
        subtitlePlaylist->append(producer, subInfo.firstFrame, subInfo.lastFrame);

        ///tempSubtitlePlaylist.append(producer, subInfo.firstFrame-correction, subInfo.lastFrame-correction);

        ///if((i+1) % nClipInTempSubtitlePlaylist == 0){
            ///subtitlePlaylist->append(tempSubtitlePlaylist);
            ///correction += tempSubtitlePlaylist.get_length();
            ///tempSubtitlePlaylist.clear();
        ///}
        ////std::cout << "==============" << std::endl;
        ////std::cout << "playlist.count :"  << subtitlePlaylist->count() << ", " <<  subtitlePlaylist->get_length() <<  std::endl;
        ////std::cout << "subInfo :" << subInfo.firstFrame << ", " << subInfo.lastFrame << std::endl;
    }
    ///subtitlePlaylist->append(tempSubtitlePlaylist);
    ///tempSubtitlePlaylist.clear();
    std::cout << "last subInfo.lastFrame :" << subtitleInfos.last().lastFrame << std::endl;
    std::cout << "subtitlePlaylist.get_length() :" << subtitlePlaylist->get_length() << std::endl;
    return subtitlePlaylist;
}

void SubtitleParser::_addPlaylistInTractor(Mlt::Playlist *subtitleTrack, int idTrack){
    int posTrackInTractorToAdd = 2;
    int posSubtitleInTractor = idTrack + posTrackInTractorToAdd;
    Mlt::Multitrack *multitrack = this->tractor->multitrack();
    multitrack->connect(*subtitleTrack, posSubtitleInTractor);

    Mlt::Profile profile("square_ntsc_wide");
    Mlt::Transition *transition = Mlt::Factory::transition(profile, (char*)"composite", NULL);
    Mlt::Properties propTrans(transition->get_properties());

    propTrans.set("out", subtitleTrack->get_length());
    delete subtitleTrack;
    propTrans.set("progressive", 1);
    propTrans.set("start", "0,0:100%x100%");
    propTrans.set("geometry", "0%,0%:100%x100%:100");
    propTrans.set("distort", 1);
    propTrans.set("fill", 1);
    this->tractor->plant_transition(transition, 0, posSubtitleInTractor);
    std::cout << "Transition planted" << std::endl;
    //TODO do the delete
}







